/*!
 * \file test_std_utils.cpp
 * \project WonderTrader
 * 
 * \brief StdUtils工具类测试套件
 * 
 * \details 测试StdUtils类的各种功能，包括：
 *          - 线程管理和同步原语
 *          - 文件操作工具
 *          - 锁管理器
 *          - 跨平台兼容性
 */

#include <gtest/gtest.h>
#include "StdUtils.hpp"
#include <fstream>
#include <chrono>
#include <thread>
#include <vector>
#include <atomic>

/*! 
 * \brief StdUtils工具类测试套件
 * 
 * \details 测试StdUtils类的基本功能，包括：
 *          - 线程创建和管理
 *          - 锁机制和同步
 *          - 文件操作
 *          - 跨平台兼容性
 */
class StdUtilsTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 测试前准备
        test_file_path = "test_std_utils_file.txt";
        test_content = "Hello, StdUtils Test!";
    }
    
    void TearDown() override {
        // 测试后清理
        if (StdFile::exists(test_file_path.c_str())) {
            std::remove(test_file_path.c_str());
        }
    }
    
    std::string test_file_path;
    std::string test_content;
};

// ========== 线程管理测试 ==========

/*!
 * \brief 测试线程创建和基本操作
 */
TEST_F(StdUtilsTest, TestThreadCreation) {
    std::atomic<bool> thread_executed(false);
    
    // 创建线程
    StdThread thread([&thread_executed]() {
        thread_executed = true;
    });
    
    // 等待线程完成
    thread.join();
    
    // 验证线程已执行
    EXPECT_TRUE(thread_executed.load());
}

/*!
 * \brief 测试线程智能指针
 */
TEST_F(StdUtilsTest, TestThreadPtr) {
    std::atomic<int> counter(0);
    
    // 创建线程智能指针
    StdThreadPtr thread_ptr = std::make_shared<StdThread>([&counter]() {
        for (int i = 0; i < 10; ++i) {
            counter++;
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }
    });
    
    ASSERT_NE(thread_ptr, nullptr);
    
    // 等待线程完成
    thread_ptr->join();
    
    // 验证计数器值
    EXPECT_EQ(counter.load(), 10);
}

// ========== 锁机制测试 ==========

/*!
 * \brief 测试递归互斥锁
 */
TEST_F(StdUtilsTest, TestRecursiveMutex) {
    StdRecurMutex mutex;
    std::atomic<int> counter(0);
    
    // 递归锁定测试
    std::function<void(int)> recursive_func = [&](int depth) {
        StdLocker<StdRecurMutex> locker(mutex);
        counter++;
        if (depth > 0) {
            recursive_func(depth - 1);
        }
    };
    
    recursive_func(5);
    
    EXPECT_EQ(counter.load(), 6); // 0到5，共6次调用
}

/*!
 * \brief 测试独占互斥锁
 */
TEST_F(StdUtilsTest, TestUniqueMutex) {
    StdUniqueMutex mutex;
    std::atomic<int> counter(0);
    std::vector<StdThreadPtr> threads;
    
    // 创建多个线程竞争同一个锁
    for (int i = 0; i < 5; ++i) {
        threads.push_back(std::make_shared<StdThread>([&mutex, &counter]() {
            for (int j = 0; j < 100; ++j) {
                StdLocker<StdUniqueMutex> locker(mutex);
                counter++;
            }
        }));
    }
    
    // 等待所有线程完成
    for (auto& thread : threads) {
        thread->join();
    }
    
    // 验证计数器值（应该是5*100=500）
    EXPECT_EQ(counter.load(), 500);
}

/*!
 * \brief 测试条件变量
 */
TEST_F(StdUtilsTest, TestConditionVariable) {
    StdUniqueMutex mutex;
    StdCondVariable cv;
    std::atomic<bool> ready(false);
    std::atomic<bool> processed(false);
    
    // 消费者线程
    StdThread consumer([&]() {
        StdUniqueLock lock(mutex);
        cv.wait(lock, [&]() { return ready.load(); });
        processed = true;
    });
    
    // 生产者线程
    StdThread producer([&]() {
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
        {
            StdUniqueLock lock(mutex);
            ready = true;
        }
        cv.notify_one();
    });
    
    consumer.join();
    producer.join();
    
    EXPECT_TRUE(ready.load());
    EXPECT_TRUE(processed.load());
}

// ========== 文件操作测试 ==========

/*!
 * \brief 测试文件内容读写（字符串版本）
 */
TEST_F(StdUtilsTest, TestFileContentStringOperations) {
    // 写入文件
    StdFile::write_file_content(test_file_path.c_str(), test_content);
    
    // 验证文件存在
    EXPECT_TRUE(StdFile::exists(test_file_path.c_str()));
    
    // 读取文件内容
    std::string read_content;
    uint64_t bytes_read = StdFile::read_file_content(test_file_path.c_str(), read_content);
    
    // 验证读取结果
    EXPECT_EQ(bytes_read, test_content.length());
    EXPECT_EQ(read_content, test_content);
}

/*!
 * \brief 测试文件内容读写（二进制版本）
 */
TEST_F(StdUtilsTest, TestFileContentBinaryOperations) {
    // 准备二进制数据
    const char binary_data[] = {0x00, 0x01, 0x02, 0x03, static_cast<char>(0xFF), static_cast<char>(0xFE)};
    size_t data_size = sizeof(binary_data);
    
    // 写入二进制数据
    StdFile::write_file_content(test_file_path.c_str(), binary_data, data_size);
    
    // 验证文件存在
    EXPECT_TRUE(StdFile::exists(test_file_path.c_str()));
    
    // 读取文件内容
    std::string read_content;
    uint64_t bytes_read = StdFile::read_file_content(test_file_path.c_str(), read_content);
    
    // 验证读取结果
    EXPECT_EQ(bytes_read, data_size);
    EXPECT_EQ(read_content.size(), data_size);
    
    // 验证二进制数据
    for (size_t i = 0; i < data_size; ++i) {
        EXPECT_EQ(static_cast<unsigned char>(read_content[i]), 
                  static_cast<unsigned char>(binary_data[i]));
    }
}

/*!
 * \brief 测试文件存在性检查
 */
TEST_F(StdUtilsTest, TestFileExists) {
    // 测试不存在的文件
    EXPECT_FALSE(StdFile::exists("non_existent_file.txt"));
    
    // 创建文件
    StdFile::write_file_content(test_file_path.c_str(), test_content);
    
    // 测试存在的文件
    EXPECT_TRUE(StdFile::exists(test_file_path.c_str()));
}

/*!
 * \brief 测试空文件操作
 */
TEST_F(StdUtilsTest, TestEmptyFileOperations) {
    // 写入空内容
    StdFile::write_file_content(test_file_path.c_str(), "");
    
    // 验证文件存在
    EXPECT_TRUE(StdFile::exists(test_file_path.c_str()));
    
    // 读取空文件
    std::string read_content;
    uint64_t bytes_read = StdFile::read_file_content(test_file_path.c_str(), read_content);
    
    // 验证结果
    EXPECT_EQ(bytes_read, 0);
    EXPECT_TRUE(read_content.empty());
}

// ========== 锁管理器测试 ==========

/*!
 * \brief 测试StdLocker的RAII特性
 */
TEST_F(StdUtilsTest, TestStdLockerRAII) {
    StdUniqueMutex mutex;
    std::atomic<bool> lock_acquired(false);
    std::atomic<bool> lock_released(false);
    
    // 测试锁的自动获取和释放
    {
        StdLocker<StdUniqueMutex> locker(mutex);
        lock_acquired = true;
        
        // 尝试在另一个线程中获取锁（应该阻塞）
        StdThread test_thread([&]() {
            if (mutex.try_lock()) {
                lock_released = true;
                mutex.unlock();
            }
        });
        
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
        test_thread.join();
        
        // 在locker作用域内，锁应该被持有
        EXPECT_FALSE(lock_released.load());
    } // locker析构，自动释放锁
    
    // 现在锁应该已经释放
    EXPECT_TRUE(lock_acquired.load());
    EXPECT_TRUE(mutex.try_lock());
    mutex.unlock();
}

// ========== 多线程压力测试 ==========

/*!
 * \brief 测试多线程文件操作
 */
TEST_F(StdUtilsTest, TestMultiThreadFileOperations) {
    const int num_threads = 5;
    const int operations_per_thread = 10;
    std::vector<StdThreadPtr> threads;
    std::atomic<int> success_count(0);
    
    // 创建多个线程同时进行文件操作
    for (int i = 0; i < num_threads; ++i) {
        threads.push_back(std::make_shared<StdThread>([&, i]() {
            for (int j = 0; j < operations_per_thread; ++j) {
                std::string file_path = "test_file_" + std::to_string(i) + "_" + std::to_string(j) + ".txt";
                std::string content = "Thread " + std::to_string(i) + " Operation " + std::to_string(j);
                
                // 写入文件
                StdFile::write_file_content(file_path.c_str(), content);
                
                // 验证文件存在
                if (StdFile::exists(file_path.c_str())) {
                    // 读取并验证内容
                    std::string read_content;
                    StdFile::read_file_content(file_path.c_str(), read_content);
                    
                    if (read_content == content) {
                        success_count++;
                    }
                    
                    // 清理文件
                    std::remove(file_path.c_str());
                }
            }
        }));
    }
    
    // 等待所有线程完成
    for (auto& thread : threads) {
        thread->join();
    }
    
    // 验证所有操作都成功
    EXPECT_EQ(success_count.load(), num_threads * operations_per_thread);
}

// ========== 边界条件和异常测试 ==========

/*!
 * \brief 测试大文件操作
 */
TEST_F(StdUtilsTest, TestLargeFileOperations) {
    // 创建大内容（1MB）
    std::string large_content(1024 * 1024, 'A');
    
    // 写入大文件
    StdFile::write_file_content(test_file_path.c_str(), large_content);
    
    // 验证文件存在
    EXPECT_TRUE(StdFile::exists(test_file_path.c_str()));
    
    // 读取大文件
    std::string read_content;
    uint64_t bytes_read = StdFile::read_file_content(test_file_path.c_str(), read_content);
    
    // 验证结果
    EXPECT_EQ(bytes_read, large_content.length());
    EXPECT_EQ(read_content, large_content);
}

/*!
 * \brief 测试特殊字符文件名
 */
TEST_F(StdUtilsTest, TestSpecialCharacterFilenames) {
    // 测试包含特殊字符的文件名
    std::vector<std::string> special_filenames = {
        "test_file_with_spaces.txt",
        "test-file-with-dashes.txt",
        "test_file_with_numbers_123.txt"
    };
    
    for (const auto& filename : special_filenames) {
        // 写入文件
        StdFile::write_file_content(filename.c_str(), test_content);
        
        // 验证文件存在
        EXPECT_TRUE(StdFile::exists(filename.c_str()));
        
        // 读取内容
        std::string read_content;
        StdFile::read_file_content(filename.c_str(), read_content);
        
        // 验证内容
        EXPECT_EQ(read_content, test_content);
        
        // 清理文件
        std::remove(filename.c_str());
    }
}

/*!
 * \brief 测试线程异常安全性
 */
TEST_F(StdUtilsTest, TestThreadExceptionSafety) {
    StdUniqueMutex mutex;
    std::atomic<bool> exception_handled(false);
    
    // 测试在锁内抛出异常的情况
    try {
        StdLocker<StdUniqueMutex> locker(mutex);
        throw std::runtime_error("Test exception");
    } catch (const std::exception&) {
        exception_handled = true;
    }
    
    // 验证异常被处理
    EXPECT_TRUE(exception_handled.load());
    
    // 验证锁已经被释放（应该能够获取锁）
    EXPECT_TRUE(mutex.try_lock());
    mutex.unlock();
} 